package cn.xiuxian.pool;

import cn.xiuxian.util.JdbcUtil;

import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

public class MyPool {

    //初始值
    private   int   initsise = 3;
    //最大连接数
    private   int   maxactive = 6;
   //当前使用的个数
    private   int  current_size = 0;
    //
    private LinkedList<Connection>  pools = new LinkedList<>();

    private  static  MyPool   instance = null;

    public  static  MyPool  getInstance(){
        if(instance ==null){
            synchronized (MyPool.class){
                if(instance ==null){
                    instance = new MyPool();
                }
            }
        }
        return  instance;
    }

    private  MyPool(){

        for (int i =0;i<initsise;i++){
            //添加连接...连接的代理对象
            //Connection conn      =>  close();  //销毁连接
            //Connection connProxy =>  close();  //可以销毁,也可以放回到连接池中.
            pools.add(createConnection());
        }
    }

    public Connection createConnection() {
        Connection  connection = null;
        Connection proxy = null;

        try {
            connection = JdbcUtil.getConnection();


            //创建conn的代理对象
            Connection finalConn =  connection;
            proxy  = (Connection) Proxy.newProxyInstance(connection.getClass().getClassLoader(), connection.getClass().getInterfaces(), new InvocationHandler() {
                @Override
                public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
                    //prepareStatement close
                    Object  obj = null;
                    if(method.getName().equals("close") && current_size <= initsise){

                        pools.add(finalConn);
                        current_size--;
                    }else if(method.getName().equals("close") && current_size > initsise){
                        current_size --;
                        pools.add(finalConn);

                    }else if(method.getName().equals("close") && current_size > maxactive){
                        current_size --;
                        finalConn.close();
                    }else{
                        obj = method.invoke(finalConn,args);
                    }
                    return obj;
                }
            });
        } catch (SQLException e) {
            e.printStackTrace();
        }

        return  proxy;
    }

    public  Connection  getConnection(){
        synchronized (pools){
            if(pools.size()>0){
                current_size ++;
                return  pools.removeLast();
            }else  if(current_size < maxactive){
                System.out.println("===初始的连接已经用完了===");
                current_size ++;
                return  createConnection();
            }else  if (current_size > maxactive){
                throw  new RuntimeException("sorry,当前池子已经达到最大值。。。");
            }
        }
        return  null;
    }

    public static void main(String[] args) throws SQLException {
        MyPool pool = MyPool.getInstance();
        Connection c1 = pool.getConnection();
        Connection c2 = pool.getConnection();
        Connection c3 = pool.getConnection();
        Connection c4 = pool.getConnection();
        Connection c5 = pool.getConnection();
        Connection c6 = pool.getConnection();
        Connection c7 = pool.getConnection();
        Connection c8 = pool.getConnection();

        System.out.println("正在使用的连接:"+pool.current_size);
        System.out.println("连接池中剩余的连接:"+pool.pools.size());

        System.out.println("============");

        c2.close();
        System.out.println("正在使用的连接:"+pool.current_size);
        System.out.println("连接池中剩余的连接:"+pool.pools.size());

    }


}
